﻿Imports System.Data.SqlClient
Imports System.IO
Imports System.Security.AccessControl

Module UnitAccessRight
    Public IfAdminPSok As Boolean
    Public strProjectCode As String
    Dim strConnection As String

    Public PBSList As New List(Of CPMS_PBS)
    Public dtHuman As New DataTable
    Dim GroupName As String
    Dim x As Integer


    ''' <summary>
    ''' 调用cmd.exe 来创建用户组
    ''' </summary>
    ''' <param name="str"></param>
    ''' <remarks></remarks>
    Public Sub RunCMD(str As String)
        Dim myProcess As Process
        Dim strIn As IO.StreamWriter

        myProcess = New Process     '打开 cmd进程
        myProcess.StartInfo.FileName = "cmd.exe"
        myProcess.StartInfo.UseShellExecute = False
        myProcess.StartInfo.CreateNoWindow = True ''是否显示DOS窗口，true代表隐藏;
        myProcess.StartInfo.RedirectStandardInput = True
        myProcess.StartInfo.RedirectStandardOutput = True
        myProcess.StartInfo.RedirectStandardError = True
        myProcess.Start()

        strIn = myProcess.StandardInput
        'Dim strOut As StreamReader = myProcess.StandardOutput
        'Dim strErr As StreamReader = myProcess.StandardError
        strIn.AutoFlush = True

        strIn.Write(str + System.Environment.NewLine)
        'strIn.Write("net user snec1 /add" + System.Environment.NewLine)              '创建User用户

        strIn.Close()
        myProcess.Close()

        myProcess = Nothing
        strIn = Nothing
    End Sub

    Public Function ConnToCPMS() As Boolean
        Dim dtPBS As New DataTable
        Try
            '从snec的CPMS系统上，读取信息



            SelectStr = <string>
            SELECT [ProjectGroupCode]
                ,[AreaCode]
                ,[AreaName]
                ,[UnitCode]
                ,[UnitName]
                ,[ProfCode]
                ,[ProfName]
                ,[HumanRole]
                ,[HumanCode]
                ,[HumanName]
            FROM [DWH].[dbo].[View_CPMS_UnitHumInfo_time]
            WHERE ProfCode IN ('PS','PM','DM','TM','WS') and ProjectGroupCode = 'xxxCode'
                              </string>.Value   'PS 工艺    PM  热工    TM   粉体
            SelectStr = SelectStr.Replace("xxxCode", strProjectCode)
            dtHuman.Reset()
            strConnection = "data source=" + "10.151.131.53" + ";initial catalog=" + "DWH" + ";user id=" + "DIS" + ";password=" + "20W16D1s2%" + ";"    '组合起来的连接字符串，帐户验证
            Dim SPIconnSql As New SqlConnection
            SPIconnSql.ConnectionString = strConnection
            Dim SPIadpsql As New SqlDataAdapter(SelectStr, SPIconnSql)

            'adapter查询出的结果集存入内存数据表
            SPIadpsql.Fill(dtHuman)

            If dtHuman.Rows.Count = 0 Then
                MessageBox.Show("该项目下查不到任何一个人员。将退出")
                Return False
            End If

            SelectStr = <string>
            SELECT  distinct [ProjectGroupCode]
                ,[AreaCode]
                ,[AreaName]
                ,[UnitCode]
                ,[UnitName]
            FROM [DWH].[dbo].[View_CPMS_UnitHumInfo_time]
            WHERE ProfCode IN ('PS','PM','DM','TM','WS') and ProjectGroupCode = 'xxxCode'
                              </string>.Value    'PS 工艺    PM  热工    TM   粉体
            SelectStr = SelectStr.Replace("xxxCode", strProjectCode)
            SPIadpsql.SelectCommand.CommandText = SelectStr
            dtPBS.Reset()
            PBSList.Clear()
            SPIadpsql.Fill(dtPBS)

            If dtPBS.Rows.Count = 0 Then
                MessageBox.Show("该项目下查不到任何一个PBS结构。将退出")
                Return False

            End If


            For Each x As DataRow In dtPBS.Rows

                PBSList.Add(New CPMS_PBS With {.AreaCode = x("AreaCode").ToString,
                                               .AreaName = x("AreaName").ToString,
                                               .UnitCode = x("UnitCode").ToString,
                                               .UnitName = x("UnitName").ToString,
                                               .IsChecked = False})
                Admin_Password.TreeView1.Nodes.Add(New TreeNode With {.Checked = False, .Text = x("AreaCode").ToString + " / " + x("UnitCode").ToString})
            Next
            Return True
        Catch ex As Exception
            Admin_Password.TreeView1.Nodes.Add(New TreeNode With {.Checked = False, .Text = "DemoArea" + "/" + "DemoUnit1"})
            Admin_Password.TreeView1.Nodes.Add(New TreeNode With {.Checked = False, .Text = "DemoArea" + "/" + "DemoUnit2"})
            PBSList.Add(New CPMS_PBS With {.AreaCode = "DemoArea",
                                              .AreaName = "DemoUnit1",
                                              .UnitCode = "DemoArea",
                                              .UnitName = "DemoUnit1",
                                              .IsChecked = False})
            PBSList.Add(New CPMS_PBS With {.AreaCode = "DemoArea",
                                              .AreaName = "DemoUnit2",
                                              .UnitCode = "DemoArea",
                                              .UnitName = "DemoUnit2",
                                              .IsChecked = False})
            MessageBox.Show(ex.Message + vbNewLine + "连接CPMS系统有误，操作将结束。")
            Return False
        End Try
    End Function

    ''' <summary>
    ''' 从snec数据库中，拿到项目的人员信息和PBS信息
    ''' </summary>
    ''' <remarks></remarks>
    Public Function GetGroupFromCPMS(PBSsChecked As List(Of CPMS_PBS)) As Boolean

        'ReadSPFData()


        '操作端是否为数据库所在机器
        Try
            Dim strHostName As String
            strHostName = System.Net.Dns.GetHostName
            'Dim strIP As String
            Dim IfHost As Boolean = False

            If strHostName.ToUpper = Mid(strPlantPath, 3, InStr(Mid(strPlantPath, 3), "\") - 1).ToUpper Then
                IfHost = True

            Else  '根据陈梦瑶的说法，取消ip地址的情况，都用计算机名来识别
                'For i = 0 To System.Net.Dns.GetHostAddresses(strHostName).Length - 1
                '    strIP = System.Net.Dns.GetHostAddresses(strHostName).GetValue(i).ToString      '存在ipv4，ipv6，或者多网卡的情况
                '    If strIP = Mid(strPlantPath, 3, InStr(Mid(strPlantPath, 3), "\") - 1) Then
                '        IfHost = True
                '    End If
                'Next

            End If
            If Not IfHost Then
                MessageBox.Show("未在SPPID数据库所在机器进行操作，操作将结束。")
                Return False
            End If
            IfHost = Nothing
        Catch ex As Exception
            MessageBox.Show(ex.Message + vbNewLine + "读取主机信息有误，操作将结束。")
            Return False
        End Try

        '建立用户组UserGroup,设计人员一组，校核人员一组

        x = MessageBox.Show("是否需要创建校审组？", "提示", MessageBoxButtons.YesNo)

        Try


            'RadForm1.RadProgressBarElement1.Minimum = 0
            'RadForm1.RadProgressBarElement1.Maximum = PBSsChecked.Count - 1

            RunCMD("net localgroup " + strProjectCode + "_" + "AllUserInSPEM" + " /add")    '创建大的用户组，方便在SPEM中管理
            For i = 0 To PBSsChecked.Count - 1
                Dim GroupName As String = strProjectCode + "_" + PBSsChecked(i).AreaCode + "_" + PBSsChecked(i).UnitCode  'plant_area_unit
                'RadForm1.RadProgressBarElement1.Value1 = i
                RunCMD("net localgroup " + GroupName + "_" + "Designer" + " /add")    '创建用户组
                If x = DialogResult.Yes Then
                    RunCMD("net localgroup " + GroupName + "_" + "Viewer" + " /add")      '创建校审组
                End If
                If x = DialogResult.Yes Then
                    For Each dtRow As DataRow In dtHuman.Select(String.Format("HumanRole='设计人员' and AreaCode='{0}' and UnitCode='{1}'", PBSsChecked(i).AreaCode, PBSsChecked(i).UnitCode))
                        RunCMD("net localgroup " + GroupName + "_" + "Designer" + " SNEC\" + dtRow("HumanCode").ToString + " /add")     '添加用户进组
                        RunCMD("net localgroup " + strProjectCode + "_" + "AllUserInSPEM" + " SNEC\" + dtRow("HumanCode").ToString + " /add")
                    Next

                    For Each dtRow As DataRow In dtHuman.Select(String.Format("HumanRole<>'设计人员' and AreaCode='{0}' and UnitCode='{1}'", PBSsChecked(i).AreaCode, PBSsChecked(i).UnitCode))  '如果只一次性cmd的话，会莫名其妙停在某个语句上
                        RunCMD("net localgroup " + GroupName + "_" + "Viewer" + " SNEC\" + dtRow("HumanCode").ToString + " /add")     '添加用户进组
                        RunCMD("net localgroup " + strProjectCode + "_" + "AllUserInSPEM" + " SNEC\" + dtRow("HumanCode").ToString + " /add")
                    Next
                Else
                    For Each dtRow As DataRow In dtHuman.Select(String.Format("AreaCode='{0}' and UnitCode='{1}'", PBSsChecked(i).AreaCode, PBSsChecked(i).UnitCode))
                        RunCMD("net localgroup " + GroupName + "_" + "Designer" + " SNEC\" + dtRow("HumanCode").ToString + " /add")     '添加用户进组
                        RunCMD("net localgroup " + strProjectCode + "_" + "AllUserInSPEM" + " SNEC\" + dtRow("HumanCode").ToString + " /add")
                    Next
                End If
            Next
            dtHuman = Nothing
            'dtPBS = Nothing  下面还要用
            'RadForm1.RadProgressBarElement1.Value1 = 0

            Return True
        Catch ex As Exception
            MessageBox.Show(ex.Message + vbNewLine + "设置用户组信息有误，操作将结束。")
            Return False
        End Try

    End Function
    ''' <summary>
    ''' 为文件夹添加权限
    ''' </summary>
    ''' <param name="FolderPath"></param>
    ''' <param name="UserGroupName"></param>
    ''' <param name="RightMode"></param>
    ''' <param name="PropagateMode"></param>
    ''' <remarks></remarks>
    Public Sub AccessFolder(ByRef FolderPath As DirectoryInfo, UserGroupName As String, RightMode As FileSystemRights, PropagateMode As PropagationFlags)
        Dim isModified As Boolean
        Dim dirSecurity As DirectorySecurity = FolderPath.GetAccessControl
        Dim DirAccessRule1 As FileSystemAccessRule = New FileSystemAccessRule(UserGroupName, RightMode,
                                                                              InheritanceFlags.ObjectInherit,
                                                                              PropagateMode, AccessControlType.Allow)


        dirSecurity.ModifyAccessRule(AccessControlModification.Add, DirAccessRule1, isModified)
        FolderPath.SetAccessControl(dirSecurity)
    End Sub

    Public Sub AccessRightAssignFromCMPS(PBSsChecked As List(Of CPMS_PBS))


        '文件夹写权限
        Try
            'ROOT
            Dim RootPath = Mid(strPlantPath, 1, InStrRev(strPlantPath, "\") - 1)
            Dim myDirInfo As DirectoryInfo
            myDirInfo = New DirectoryInfo(RootPath)
            AccessFolder(myDirInfo, strProjectCode + "_" + "AllUserInSPEM", FileSystemRights.Modify, PropagationFlags.NoPropagateInherit)

            'file in root
            Dim fileInfo As FileInfo
            Dim fileSecurity As FileSecurity
            Dim fileAccessRule1 As FileSystemAccessRule
            Dim isModified As Boolean
            For Each fileInfo In myDirInfo.GetFiles
                Try
                    fileSecurity = fileInfo.GetAccessControl
                    fileAccessRule1 = New FileSystemAccessRule(strProjectCode + "_" + "AllUserInSPEM", FileSystemRights.Modify, AccessControlType.Allow)
                    fileSecurity.ModifyAccessRule(AccessControlModification.Add, fileAccessRule1, isModified)
                    fileInfo.SetAccessControl(fileSecurity)
                Catch ex As Exception

                End Try
            Next

            'FOLDER IN ROOT
            For Each mySubDirInfo As DirectoryInfo In myDirInfo.GetDirectories
                Try
                    If mySubDirInfo.FullName = strPlantPath Then
                        'plant structure的folder，只对自己生效
                        AccessFolder(mySubDirInfo, strProjectCode + "_" + "AllUserInSPEM", FileSystemRights.Modify, PropagationFlags.NoPropagateInherit)
                        For Each AreaDirInfo As DirectoryInfo In mySubDirInfo.GetDirectories
                            'AREA的folder，只对自己生效
                            AccessFolder(AreaDirInfo, strProjectCode + "_" + "AllUserInSPEM", FileSystemRights.Modify, PropagationFlags.NoPropagateInherit)
                        Next
                    Else
                        '除plant structure之外的folder，子文件夹都继承
                        AccessFolder(mySubDirInfo, strProjectCode + "_" + "AllUserInSPEM", FileSystemRights.Modify, PropagationFlags.None)
                    End If
                Catch ex As Exception

                End Try

            Next



            'loop unit folder
            For i = 0 To PBSsChecked.Count - 1
                'RadForm1.RadProgressBarElement1.Value1 = i
                GroupName = strProjectCode + "_" + PBSsChecked(i).AreaCode + "_" + PBSsChecked(i).UnitCode  'plant_area_unit

                Try
                    myDirInfo = New IO.DirectoryInfo(strPlantPath + "\" + PBSsChecked(i).AreaCode + "\" + PBSsChecked(i).UnitCode)   '尽量前面加计算机名,如sppid05\snec
                    AccessFolder(myDirInfo, GroupName + "_Designer", FileSystemRights.Modify, PropagationFlags.None)
                    If x = DialogResult.Yes Then
                        '对应校核人员，viewer的，只读权限
                        AccessFolder(myDirInfo, GroupName + "_Viewer", FileSystemRights.Read, PropagationFlags.None)
                    End If
                Catch
                    '如果没有这个文件夹的情况
                    GoTo NextFolder
                End Try

NextFolder:
            Next
            'RadForm1.RadProgressBarElement1.Value1 = 0

            'dtPBS = Nothing
        Catch ex As Exception
            MessageBox.Show(ex.Message + vbNewLine + "设置SPPID项目Plant下，Unit文件夹的权限错误，操作将结束。")
            Exit Sub
        End Try
        MessageBox.Show("权限分配结束。")

    End Sub

End Module
